<?php

namespace App\Http\Controllers\Api\V1;

use Carbon\Carbon;
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Support\Facades\Cache;
use App\Supports\Auth\Alipay\AlipayBinder;
use App\Supports\Auth\Alipay\AlipayLogger;
use App\Services\AuthOneDevice\AuthOneDevice;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use App\Http\Controllers\Api\V1\Requests\AuthStoreRequest;
use App\Http\Controllers\Api\V1\Requests\AuthWxminiRequest;
use App\Http\Controllers\Api\V1\Requests\AuthAlipayRequest;
use App\Http\Controllers\Api\V1\Requests\AuthAlipayBindRequest;
use App\Http\Controllers\Api\V1\Requests\AuthWechatBindRequest;
use App\Http\Controllers\Api\V1\Requests\MerchantAuthStoreRequest;
use App\Models\RegisterPhone;
use Rainsens\Dinglog\Facades\Dinglog;
use EasyWeChat\Factory;
use App\Services\RegisterNewUser\RegisterNewUser;
use App\Models\User;
use App\Models\Merchant;
use App\Supports\Sms\Sms;
use Illuminate\Support\Facades\Hash;
use GuzzleHttp\Client;
use Illuminate\Support\Str;

class AuthController extends Controller
{
	public function store()
	{
		$lock = Cache::lock('send_sms_code', 15);

		try {

			if (!$lock->get()) fail('请稍后重试');

			$request = app(AuthStoreRequest::class);

			/*$credentials['phone'] = request('phone');
			$credentials['password'] = 000000;


			$token = auth('api')->setTTL(config('api.auth_ttl'))->attempt($credentials);*/

			$user = User::query()->where('phone',$request->phone);

			if($user->first()){
				if ($user->first()->last_token) { 
					try {
						$credentials['phone'] = request('phone');
						$credentials['password'] = 000000;

						$token = auth('api')->setTTL(config('api.auth_ttl'))->attempt($credentials);

					} catch (TokenExpiredException $e) {}
				}

				//$user->update(['last_token' => $token]);

				
			}else{
				
				app(RegisterNewUser::class, [
					'phone' => $request->phone,
					'inviteCode' => $request->invite_code
				])->register();

				$credentials['phone'] = request('phone');
				$credentials['password'] = 000000;


				$token = auth('api')->setTTL(config('api.auth_ttl'))->attempt($credentials);
			}
			app(Sms::class)->cleanCachedDataAfterUsing(request('sms_key'));

			$user->update(['last_token' => $token]);

		} finally {
			$lock->release();
		}

		return $this->respondWithToken($token)->setStatusCode(201);
	}

	 public function wxLogin()
    {
    	$client = new Client(['Content-Type' => 'application/json']);
	    $code = request('code', '');
	    if (!$code) fail('无法登录');

	    $params = [
	    	'appid'=>env("WECHAT_OPEN_PLATFORM_APPID"),
	        'secret'=>env("WECHAT_OPEN_PLATFORM_SECRET"),
	        'code'=>$code,
	        'grant_type'=>'authorization_code'
	    ];
	     $response = $client->get("https://api.weixin.qq.com/sns/oauth2/access_token", ["query"=>$params]);

	     $body = $response->getBody(); // 获取响应体
   		 $content = $body->getContents(); // 获取响应内容

   		 $content = json_decode($content,true);

   		 if(isset($content['access_token'])){

   		 	$reParams = [
   		 		'access_token'=>$content['access_token'],
   		 		'openid'=>$content['openid'],
   		 		'lang'=>'zh_CN',
   		 	];

   		 	$openid = $content['openid'];

   		 	 $response = $client->get("https://api.weixin.qq.com/sns/userinfo", ["query"=>$reParams]);

		     $body = $response->getBody(); // 获取响应体
	   		 $content = $body->getContents(); // 获取响应内容
	   		 $userInfo = json_decode($content,true);


	   		 $user= User::query()->where("wx_openid",$openid)->first();
	   		 if (isset($user->last_token)) { 
				try {
					$credentials['phone'] = 13000000000;
					$credentials['password'] = 000000;

					$token = auth('api')->setTTL(config('api.auth_ttl'))->attempt($credentials);


					$user->update(['last_token' => $token]);
				} catch (TokenExpiredException $e) {}
			}else{

				$credentials['phone'] = 13000000000;
				$credentials['password'] = 000000;


				
				User::create([
					'grade' => 'noraml',
					'phone' => $credentials['phone'],
					'wx_openid'=>$openid,
					'name'=>$userInfo['nickname'],
					'wx_headimgurl'=>$userInfo['headimgurl'],
					'password' => bcrypt(000000),
					
				]);

				 $user= User::query()->where("wx_openid",$openid)->first();


				$token = auth('api')->setTTL(config('api.auth_ttl'))->attempt($credentials);

				$user->update(['last_token' => $token]);
			}
	   		 
	   		 return $this->respondWithToken($token)->setStatusCode(201);
   		 }

   		 fail('无法登录');
	     //if($response)
	      /*$params = {
		        'access_token': token_response['access_token'],
		        'openid': token_response['openid'],
		        'lang': 'zh_CN',
		    }
		  $user_info = $client->get("https://api.weixin.qq.com/sns/userinfo", $params); */
    }


	public function merchantAuth()
	{
		$lock = Cache::lock('merchant_auth', 15);

		try {

			if (!$lock->get()) fail('请稍后重试');

			$request = app(MerchantAuthStoreRequest::class);

			/*$credentials['phone'] = request('phone');
			$credentials['password'] = 000000;


			$token = auth('api')->setTTL(config('api.auth_ttl'))->attempt($credentials);*/

			$merchant = Merchant::query()->where('name',$request->name)->first();

			if($merchant){
				
				$credentials['name'] = request('name');
			
				if(empty($merchant->password)){

					fail("商户未设置密码，请联系商管设置密码！");
				}

				if (!Hash::check(request('password'), $merchant->password)) {
					return fail("密码错误！");
				}
				/*dd($truePassword);
				if($truePassword != $merchant->password ){
					fail("密码错误！");
				}*/
				$credentials['password'] =  request('password');

				$token = auth('merchant')->setTTL(config('api.auth_ttl'))->attempt($credentials);

			}else{
				fail("商户不存在！");

			}

		} finally {
			$lock->release();
		}

		return $this->respondWithToken($token)->setStatusCode(201);
	}

	public function alipayPayload()
	{

		$request = app(AuthAlipayBindRequest::class);
		
		$payload = app(AlipayLogger::class)->appPayload();
		Dinglog::text(json_encode($payload->getContent()));
		return response()->json(['payload' => $payload->getContent()]);
	}


	public function alipay()
	{
		$user = app(AlipayLogger::class)->login();
		$token = auth('api')->setTTL(config('api.auth_ttl'))->login($user);
		auth('api')->user()->update(['last_logged_at' => Carbon::now()]);
		return $this->respondWithToken($token)->setStatusCode(201);
	}

	public function alipayBind()
	{
		$lock = Cache::lock('alipay_bind', 30);

		try {

			if (! $lock->get()) fail('处理中...请勿频繁操作');

			
			$user = request()->user();

			app(AlipayBinder::class)->bind($user);

		} finally {
			$lock->release();
		}

		return response(null, 204);
	}

    public function update()
    {
	    if ($user = auth('api')->user()) {
    	    $token = auth('api')->setTTL(config('api.auth_ttl'))->refresh();
	    	app(AuthOneDevice::class)->auth($user, $token);
    	    return $this->respondWithToken($token);
	    }

	    auth('api')->logout();
	    return response(null, 204);
    }

    public function logout()
    {
    	if ($user = auth('api')->user()) {
    		//$user->delFromCache();
	    }

	    auth('api')->logout();
	    return response(null, 204);
    }

    public function wechatBind()
    {
	    $user = app(WechatBinder::class)->bind(request()->user());
	    return new UserResource($user);
    }

    public function jsTicket()
    {

    	$url = request("url");
	    $appid = config('wechat.open_platform.default.app_id');
	    $secret = config('wechat.open_platform.default.secret');
	    
	    $accessToken = Cache::remember('access_token', 120, function() use ($appid, $secret) {
	        $response = file_get_contents("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret");
	        return json_decode($response)->access_token;
	    });

	    $ticket = Cache::remember('jsapi_ticket', 120, function() use ($accessToken) {
	        $response = file_get_contents("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&type=jsapi");
	        return json_decode($response)->ticket;
	    });

	    $nonceStr = Str::random(16);
	    $timestamp = time();
	    $signature = sha1("jsapi_ticket=$ticket&noncestr=$nonceStr&timestamp=$timestamp&url=$url");

	     return [
	        'appId' => $appid,
	        'timestamp' => $timestamp,
	        'nonceStr' => $nonceStr,
	        'signature' => $signature
	    ];
    }

     public function wechat()
    {
	     $app = Factory::officialAccount(config('wechat.open_platform.default'));
        
	    
        if (request('signature', '') && request('echostr', '')) {
	        $signature = request('signature', '');
	        $echostr = request('echostr', '');
	        $timestamp = request('timestamp', '');
	        $nonce = request('nonce', '');
	 
	        $token = $app->config['token'];


	 
	        $tmpArr = array($token, $timestamp, $nonce);
	        sort($tmpArr, SORT_STRING);
	        $tmpStr = implode($tmpArr);
	        $tmpStr = sha1($tmpStr);
	 
	        if ($tmpStr == $signature) {
	            return response($echostr);
	        } else {
	            return response('Invalid signature');
	        }
	    }
       // return $response->send();
        //dd($response);
        //$response->send(); // Laravel 里请使用：return $response;
    }

    public function destroy()
    {
    	if ($user = auth('api')->user()) {
    		$register = RegisterPhone::query()->where("phone",$user->phone)->first();
    		$register->update(['deleted_at'=>Carbon::now()]);
    		$user->delFromCache();
    		$user->delete();
	    }

    	auth('api')->logout();

    	return response(null, 204);
    }

    protected function respondWithToken(string $token)
    {
    	$expiredAt = auth('api')->factory()->getTTL(); // minutes.
    	return response()->json([
    		'access_token' => $token,
		    'token_type' => 'Bearer',
		    'refresh_at' => ($expiredAt - 14400) * 60, // minus 10 days.
		    'expired_at' => $expiredAt * 60, // seconds.
	    ]);
    }
}
